<template>
  <div class="this-chart" ref="box" :id="chartId"></div>
</template>
<script>
  import ResizeObserver from 'resize-observer-polyfill'
  import * as echarts from 'echarts'
  export default {
    props: {
      option: {
        type: Object,
        default: () => {
          return {
            backgroundColor: '#fff0',
            grid: {
              left: '1%',
              right: '1%',
              bottom: '3%',
              containLabel: true,
            },
            tooltip: {},
            legend: {
              textStyle: {
                fontSize: 12,
                color: '#BCE0FF',
              },
            },
            xAxis: {
              axisLine: {
                lineStyle: {
                  color: '#BCE0FF',
                },
              },
              data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
            },
            yAxis: {
              axisLine: {
                lineStyle: {
                  color: '#BCE0FF',
                },
              },
              axisLabel: {
                margin: 10,
                textStyle: {
                  fontSize: 14,
                },
              },
              splitLine: {
                lineStyle: {
                  color: 'rgba(217, 231, 255, 0.12)',
                },
              },
            },
            series: [
              {
                name: 'Sale',
                type: 'bar',
                data: [5, 20, 36, 10, 10, 20, 4],
              },
            ],
          }
        },
      },
      opts: {
        type: Object,
        default: () => {
          return {
            renderer: 'canvas',
          }
        },
      },
    },
    data() {
      return {
        chartId: 'myChart-' + ~~(Math.random() * 10000) + new Date().getTime(), //chart的id
        chartDom: null, // chart对应的dom
        chartInstance: null, // echart实例
        resizeTimer: null, //计数器
        chartOption: null, // echart的配置项option
        resizeAble: true, //是否可以resize
        isMounted: false,
        robserver: null,
      }
    },
    watch: {
      option: {
        handler(val) {
          // option变化时重新初始化
          this.initChart(val)
        },
        deep: true,
      },
    },
    activated() {
      // 页面激活后重新resize
      this.resizeAble = true
      if (this.isMounted) {
        this.isMounted = false
      } else {
        this.chartResize()
      }
    },
    deactivated() {
      // 页面隐藏后禁止resize
      this.resizeAble = false
    },
    created() {},
    mounted() {
      this.isMounted = true
      this.initChart(this.option)
      if (this.robserver === null) {
        this.robserver = new ResizeObserver(
          this.debounce(entries => {
            // eslint-disable-next-line no-restricted-syntax
            for (const entry of entries) {
              const { width } = entry.contentRect
              // console.log('Element:', entry.target)
              // console.log(`Element's size: ${width}px x ${height}px`)
              // console.log(`Element's paddings: ${top}px ; ${left}px`)
              if (width) {
                this.chartResize()
              }
            }
          }, 10)
        )
      }
      this.robserver.observe(this.$refs.box)
    },
    unmounted() {},
    methods: {
      initChart(option) {
        this.chartDom = document.getElementById(this.chartId)
        if (this.chartInstance === null && this.chartDom) {
          this.chartInstance = echarts.init(
            this.chartDom,
            null,
            this.opts
          )
        }
        if (option) {
          this.chartOption = option
          if (this.chartInstance) {
            this.chartInstance.clear()
            this.chartInstance.setOption(option)
            if (this.opts?.renderer === 'svg') {
              this.rendererIsDvgChange()
            }
          }
        }
      },
      rendererIsDvgChange() {
        let images = document
          .getElementById(this.chartId)
          .getElementsByTagName('image')
        for (let i = 0, len = images.length; i < len; i++) {
          images[i].setAttribute('preserveAspectRatio', 'none')
          images[i].setAttribute('vector-effect', 'non-scaling-stroke')
        }
      },
      debounce(fn, delay) {
        let timer = null
        return function (...args) {
          if (timer) clearTimeout(timer)
          timer = setTimeout(
            () => {
              if (typeof fn === 'function') {
                fn.apply(null, args)
              }
              clearTimeout(timer)
            },
            delay > 0 ? delay : 100
          )
        }
      },
      chartResize() {
        const width = this.$refs.box.offsetWidth
        const height = this.$refs.box.offsetHeight
        if (this.chartInstance) {
          this.chartInstance.dispose()
          this.chartInstance = null
        }
        let baseLen = 0
        if (width > height) {
          baseLen = height
        } else {
          baseLen = width
        }
        if (this.option.graphic) {
          this.option.graphic.elements[0].style.width = baseLen * 0.9
          this.option.graphic.elements[0].style.height = baseLen * 0.6
          this.option.graphic.elements[1].style.width = baseLen * 0.45
          this.option.graphic.elements[1].style.height = baseLen * 0.45
        }
        this.initChart(this.option)
      },
    },
  }
</script>
<style scoped>
  .this-chart {
    width: 100%;
    height: 100%;
  }
</style>
